import { clear } from '@/utils/storage'
import router from '@/router'
import store from '@/store'
import { nanoid } from 'nanoid'
import { EventBus } from '@/utils/eventBus'

/**
 * 退出登录
 */
export function logout () {
  // 清空本地存储
  clear()
  // 已经连接的websocket断开连接
  store.state.network.ws.close()
  // websocket重置
  store.commit('changeWsInstance', null)
  // 清空菜单信息
  store.commit('setMenuTree', {
    menuTree: []
  })
  store.commit('setMenuList', {
    menuList: []
  })
  store.commit('changeUserInfo', null)
  // 清空导航信息
  store.commit('setNavList', [])
  router.push({
    path: '/login'
  })
}

/**
 * 连接list集合
 * @param list 集合
 * @param name 名称
 * @param split 连接符
 * @param isSplit 是否拼接
 */
export const joinList = (list, name, split, isSplit = true) => {
  const temp = []
  list.forEach(item => {
    temp.push(item[name])
  })
  if (isSplit) {
    return temp.join(split)
  } else {
    return temp
  }
}

/**
 * 节流
 * @param func
 * @param delay
 * @returns {(function(): void)|*}
 */
export const throttle = (fn, delay) => {
  let canRun = true
  return function () {
    if (!canRun) return
    canRun = false
    setTimeout(() => {
      fn.apply(this, arguments)
      canRun = true
    }, delay)
  }
}
/**
 * 高亮文本
 * @param originStr 源字符串
 * @param element 元素
 * @param className class类名
 * @param keyword 关键词
 * @returns {*|string|string}
 */
export const highLight = (originStr, element, className, keyword) => {
  if (!originStr || !keyword || !originStr.includes(keyword)) {
    console.log(111, originStr, keyword)
    return originStr
  }
  const str = originStr.replaceAll(keyword, `<${element} class=${className}>${keyword}</${element}>`)
  return str
}
/**
 * eventbus实例
 * @type {EventBus}
 */
export const emitter = new EventBus()

/**
 * 生成唯一id
 */
export const generateId = (size = 18) => {
  return nanoid(size)
}
/**
 * 数组转化为树形结构
 * @param list 集合
 * @param id 唯一id
 * @param pid 关联id
 * @returns {*[]}
 */
export const convertListToTree = (list, id = 'id', pid = 'pid') => {
  const trees = []
  if (!Array.isArray(list)) {
    throw new Error('list必须为数组')
  }
  // 缓存所有的id与值
  const idMap = new Map()
  list.forEach(item => {
    idMap.set(item[id], item)
    if (!idMap.has(item[pid])) {
      trees.push(item)
    } else {
      findChild(trees, item[pid], item, id)
    }
  })
  return trees
}
const findChild = (list, pid, data, id = 'id') => {
  list.forEach(item => {
    item.children = (!item.children ? [] : item.children)
    if (item[id] === pid) {
      item.children.push(data)
    } else {
      if (item.children.length) {
        findChild(item.children, pid, data)
      }
    }
  })
}
/**
 * 排序树形结构（数组对象）
 * @param list 待处理数据
 * @param sortName 排序名
 * @param children 子元素
 * @param desc 是否是升序
 * @returns {*}
 */
export const sort = (list, sortName = 'sort', children = 'children', desc = true) => {
  if (!Array.isArray(list)) {
    throw new Error('list必须为数组')
  }
  const tempList = list.concat([])
  sortChildren(tempList, sortName, children, desc)
  return tempList
}
const sortChildren = (list, sortName = 'sort', children = 'children', desc = true) => {
  list.sort((item1, item2) => {
    return desc ? item1[sortName] - item2[sortName] : item2[sortName] - item1[sortName]
  })
  list.forEach(item => {
    if (Array.isArray(item[children])) {
      sortChildren(item.children, sortName, children)
    }
  })
}
// 字节转换
export const byteConvert = (bytes) => {
  if (isNaN(bytes)) {
    return ''
  }
  const symbols = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
  let exp = Math.floor(Math.log(bytes) / Math.log(2))
  if (exp < 1) {
    exp = 0
  }
  const i = Math.floor(exp / 10)
  bytes = bytes / Math.pow(2, 10 * i)

  if (bytes.toString().length > bytes.toFixed(2).toString().length) {
    bytes = bytes.toFixed(2)
  }
  return bytes + ' ' + symbols[i]
}

/**
 * 获取当前日期
 * @param separator
 * @returns {string}
 */
export const getCurrentDate = (separator = '-') => {
  const tempYearMonthDay = []
  tempYearMonthDay.push(new Date().getFullYear())
  tempYearMonthDay.push((new Date().getMonth() + 1).toString().padStart(2, '0'))
  tempYearMonthDay.push(new Date().getDate().toString().padStart(2, '0'))
  return tempYearMonthDay.join(separator)
}
